package com.koron.order.linepatrol.satellite.excel;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.util.ListUtils;
import com.koron.bean.base.Response;
import com.koron.order.linepatrol.satellite.bean.convertor.LinePatrolMonitorChangeConvertor;
import com.koron.order.linepatrol.satellite.bean.excel.LinePatrolMonitorChangeExcel;
import com.koron.order.linepatrol.satellite.bean.po.LinePatrolMonitorChange;
import com.koron.order.linepatrol.satellite.service.LinePatrolMonitorChangeService;
import com.koron.order.overhaul.bean.dto.Equipment;
import com.koron.order.risk.feign.LineEquipmentFeign;
import com.koron.order.risk.feign.dto.EquipmentParams;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.ADOConnection;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author jzp
 * @since 2023/2/9
 */
@Slf4j
@AllArgsConstructor
public class LinePatrolMonitorChangeExcelListener extends LineAnalysisEventListener<LinePatrolMonitorChangeExcel> {

    private final LinePatrolMonitorChangeService linePatrolMonitorChangeService;
    private final LineEquipmentFeign equipmentFeign;
    private final LinePatrolMonitorChangeConvertor linePatrolMonitorChangeConvertor;
    private final String monitorId;

    // 每隔100条，然后清理list，方便内存回收
    private static final int BATCH_COUNT = 100;
    // 要保存的数据
    private final List<LinePatrolMonitorChange> linePatrolMonitorChangeList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);


    @Override
    public void invoke(LinePatrolMonitorChangeExcel data, AnalysisContext context) {
        LinePatrolMonitorChange linePatrolMonitorChange = fillData(data);
        if (linePatrolMonitorChange == null) {
            return;
        }
        linePatrolMonitorChangeList.add(linePatrolMonitorChange);
        if (linePatrolMonitorChangeList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            linePatrolMonitorChangeList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        log.info("所有数据解析完成！");
    }

    private void saveData() {
        computeManageDept();
        ADOConnection.runTask(getCurrDs(), linePatrolMonitorChangeService, "saveBatch", Boolean.class, linePatrolMonitorChangeList);
        log.info("存储数据库成功！");
    }

    private void computeManageDept() {
        List<String> ids = linePatrolMonitorChangeList.stream().map(LinePatrolMonitorChange::getTowerId).collect(Collectors.toList());

        Response<List<EquipmentParams>> batchBaseParams = equipmentFeign.getBatchBaseParams(ids);
        if (CollUtil.isEmpty(batchBaseParams.getData())) {
            return;
        }

        List<EquipmentParams> data = batchBaseParams.getData();
        Map<String, EquipmentParams> deptMap = data.stream()
                .filter(e -> "管理部门".equals(e.getParamName()))
                .collect(Collectors.toMap(EquipmentParams::getEquipmentId, e -> e, (o1, o2) -> o1));
        for (LinePatrolMonitorChange linePatrolMonitorChange : linePatrolMonitorChangeList) {
            EquipmentParams params = deptMap.get(linePatrolMonitorChange.getTowerId());
            linePatrolMonitorChange.setBelongDeptId(params.getParamResult());
            linePatrolMonitorChange.setBelongDeptName(params.getParamValue());
        }

    }

    private LinePatrolMonitorChange fillData(LinePatrolMonitorChangeExcel data) {
        if (data == null) {
            return null;
        }
        LinePatrolMonitorChange linePatrolMonitorChange = linePatrolMonitorChangeConvertor.excelToEntity(data);
        linePatrolMonitorChange.setMonitorId(monitorId);

        // riskParentType默认高压线路
        linePatrolMonitorChange.setRiskParentType("高压线路");
        // 导入巡视记录时，初始核实状态为待核实
        linePatrolMonitorChange.setCheckStatus("1");

        String lineName = linePatrolMonitorChange.getEquipmentName();
        if(lineName == null){
            fillError(data,0,"线路名称不能为空");
        }
        Equipment line = getLineByName(linePatrolMonitorChange.getEquipmentName());
        if (line == null) {
            fillError(data, 0, "线路：" + linePatrolMonitorChange.getEquipmentName() + "不存在");
            return null;
        }  else {
            linePatrolMonitorChange.setEquipmentId(line.getId());
        }

        //风险等级校验
        if(linePatrolMonitorChange.getRiskLevel()== null)
        {
            fillError(data,1,"风险子类不能为空");
            return null;
        }

        // 杆塔
        if (StrUtil.isEmpty(linePatrolMonitorChange.getTowerName())) {
            fillError(data, 4, "杆塔不能为空");
            return null;
        }
        Equipment tower = getTowerByNameAndChildren(line.getName(), linePatrolMonitorChange.getTowerName(), line.getChildren());
        if (tower == null) {
            fillError(data, 4, "杆塔：" + data.getTowerNumber() + "不存在");
            return null;
        }  else {
            linePatrolMonitorChange.setTowerId(tower.getId());
        }

        //数字校验
        boolean number0 = NumberUtil.isNumber(data.getDistanceLine());
        boolean number1 = NumberUtil.isNumber(data.getDistanceTower());
        boolean number2 = NumberUtil.isNumber(data.getLongitude());
        boolean number3 = NumberUtil.isNumber(data.getLatitude());
        if(!number0){
            fillError(data,2,"距线路最近距离输入非数值型，不是整数或小数");
            return null;
        }
        linePatrolMonitorChange.setEquipmentDistance(Integer.valueOf(data.getDistanceLine()));

        if(!number1){
            fillError(data,3,"距杆塔最近距离输入非数值型，不是整数或小数");
            return null;
        }
        linePatrolMonitorChange.setTowerDistance(Integer.valueOf(data.getDistanceTower()));

        if(!number2){
            fillError(data,5,"经度输入非数值型，不是整数或小数");
            return null;
        }

        if(!number3){
            fillError(data,6,"纬度输入非数值型，不是整数或小数");
            return null;
        }


        return linePatrolMonitorChange;
    }

}
